import { fjAndDgDataCode, intl, resDataFilter } from '@/utils';
import type dxContextMenu from 'devextreme/ui/context_menu';
import notify from 'devextreme/ui/notify';
import React, {
  useCallback,
  useEffect,
  useImperativeHandle,
  useMemo,
  useRef,
  useState,
} from 'react';
import { useModel } from 'umi';
import { draftManageUploadBatch, getAuditPhase } from '../service';
import PhaseLnputDialog from './components/PhaseLnputDialog';
import './index.less';
import {
  deletePhase,
  deletePhaseContent,
  newPhase,
  paperNumber,
  PhaseMobile,
  PhaseName,
} from './service';

import Popup from 'devextreme-react/popup';

import type { PhaseItem } from '../data';
import YearlyAuditPaperForm from './components/yearlyAudit';

// import { HocSortableTree } from '~/public/cpas-ui/components-bs/TreeGridDrag/HocSortable';
import { CpasIcon, SortableDevTree } from '~/public/cpas-ui';
import AuditPaperDeleteDialog from './components/AuditPaperDeleteDialog';
import style from './index.less';
// import DevInputPopup from '~/public/cpas-ui/components-ui/express-components/DevPopup';
import { modalExtensions } from '@/pages/AuditPaper';
import DevDefaultPopup from '~/public/cpas-ui/components-ui/express-components/DevPopup/DevPopup';

/**
 * 底稿阶段树 组件
 * @param props
 * @returns
 */

// const SortableTree = HocSortableTree(DevTree.Default);
const PhaseTree = React.forwardRef((props: any, ref) => {
  const { initialState } = useModel('@@initialState');
  const { zcbfid, dbname, sjxmbh } = initialState?.curPart as API.CurPart;
  const { username, usercode } = initialState?.curUser as API.CurUser;
  const { canEdit, onMenuItemClieck, treeItemClick } = props;
  const [treeData, setTreeData] = useState<any[]>([]);
  const AuditPaperDeleteDialogRef = useRef<any>(); // 模板
  const InputDialogRef = useRef<any>(); // 模板

  const PhaseLnputDialogRef = useRef<any>(); // 模板
  // const [phaseTitle, setPhaseTitle] = useState<any>([]);

  const curNodeRef = useRef<PhaseItem>(); // 当前操作的node
  // 函数组件 不能使用 createRef,需要使用useRef
  const treeViewRef = React.useRef<any>();
  const tplDialogErrorRef = React.useRef<any>();

  // const contextMenuRef = React.useRef<ContextMenu>(null);
  const [showYearlyAuditPaper, setShowYearlyAuditPaper] = useState<boolean>(false);
  const [HidingState, setHidingState] = useState<boolean>(true);
  const selNodeIDText = React.useRef<any>('');
  const Divstyle: React.CSSProperties = {
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    width: '35px',
    height: '31px',
    marginRight: '5px',
    marginLeft: '5px',
  };

  const getRefTree = () => {
    if (treeViewRef.current) {
      return treeViewRef.current?.treeRef.current.instance;
    }
  };

  /**
   * 过滤找不到pid的阶段
   * @param data
   */
  function filterNullPid(data) {
    const idMap = {};

    // 构建 id 到索引的映射关系
    for (let i = 0; i < data.length; i++) {
      const item = data[i];
      idMap[item.id] = i;
    }

    const filterData = data.filter(function (item) {
      const pid = item.pid;
      if (idMap[pid] !== undefined || pid === 'all' || pid === null) {
        return true;
      } else {
        return false;
      }
    });

    return filterData;
  }

  const selectTreeNode = (nodeID: string) => {
    setTimeout(async () => {
      const refTree = getRefTree();
      await refTree.selectItem(nodeID);
      selNodeIDText.current = nodeID;
      const treeNode = refTree.getSelectedNodes();
      console.log(treeNode, '@@@ treeNode');
      treeItemClick(treeNode[0]?.itemData);
      refTree.expandItem(nodeID);
    }, 100);
  };

  const fetchData = async (nodeID: string = '') => {
    const res = await getAuditPhase({ dbname, zcbfid });
    if (res.success) {
      const data = filterNullPid(res.data);
      setTreeData(data);
      if (nodeID) {
        selectTreeNode(nodeID);
      } else {
        const tempData = data
          .filter((item: any) => item.pid === 'all' && item.lx === 1)
          .sort((a: any, b: any) => {
            return a.xh - b.xh;
          });
        const selData = tempData[0];
        selectTreeNode(selData.id);
      }
    }
  };

  useEffect(() => {
    // 获取 审计阶段列表
    if (dbname) {
      fetchData();
    }
  }, [dbname]);

  // 自定义方法
  useImperativeHandle(ref, () => ({
    refresh: () => {
      fetchData(selNodeIDText.current);
    },
  }));

  /**
   * 获取年度节点数量
   */
  const getYearCnt = useCallback(() => {
    const refTree = getRefTree();
    const nodes = refTree.getNodes();
    let cnt = 0;
    nodes?.forEach((item: any) => {
      if (item.itemData.lx == 1) {
        cnt++;
      }
    });
    return cnt;
  }, []);

  // 阶段操作(new, rename)
  const editPhase = (item: PhaseItem | undefined, opt: 'new' | 'edit') => {
    if (!item) {
      console.log('item is undefined');
      return;
    }
    const props = {
      title: opt == 'new' ? '新建阶段' : '修改阶段',
      value: opt == 'new' ? '' : item?.text,
    };

    InputDialogRef.current.show({
      ...props,
      regExpFunc: (v: any) => {
        const reg = /^[\s\S]*.*[^\s][\s\S]*$/;
        if (reg.test(v)) {
          return true;
        } else {
          notify('阶段名称不能有.后缀！', 'warning', 2000);
          return false;
        }
      },
      okCallback: async (v: any) => {
        if (!v) return;
        console.log(v, '----------');
        const patt = new RegExp(/^\s+|\s+$/g, '');
        const result = patt.test(v);
        if (result) return notify('请输入正确的名称', 'warning', 3000);
        if (opt === 'new') {
          const r = await newPhase(
            v,
            item?.dgnd,
            item.pid === 'all' ? null : item?.text,
            zcbfid,
            username,
            dbname,
          );
          if (r.success) {
            const resFilter = resDataFilter(r.data);
            if (resFilter.success) {
              const { reDataArr } = resFilter;
              if (reDataArr.tempError.length) {
                const resNew = fjAndDgDataCode(reDataArr.tempError[0].code);
                return notify(`${resNew}!`, 'error', 3000);
              }
              notify('保存成功', 'success', 2000);
              fetchData(`${item?.dgnd}${v}`);
            } else {
              notify('保存失败', 'error', 2000);
            }
          } else {
            notify('保存失败', 'error', 2000);
          }
        } else {
          // notify('修改：' + node.text + '为：' + v);
          if (item.jdlx === '.') {
            notify('此数据不可修改', 'warning', 3000);
          } else {
            console.log(item);
            // debugger;
            const res = await PhaseName(item.id, sjxmbh, v, dbname, item.Guid);
            if (res.success) {
              const resFilter = resDataFilter(res.data);
              if (resFilter.success) {
                const { reDataArr } = resFilter;
                if (reDataArr.tempError.length) {
                  const resNew = fjAndDgDataCode(reDataArr.tempError[0].code);
                  return notify(`${resNew}!`, 'error', 3000);
                }
                notify('修改成功', 'success', 2000);
                fetchData(`${item?.dgnd}${v}`);
              } else {
                notify('修改失败', 'error', 2000);
              }
            } else {
              notify('修改失败', 'error', 2000);
            }
          }
        }
      },
    });
  };

  // 删除阶段
  const delPhase = async (item: PhaseItem | undefined) => {
    if (!item) {
      return;
    }
    if (item.lx === 1) {
      if (getYearCnt() < 2) {
        notify(
          intl('An annual.keep', '至少需要保留一个年度底稿,最后一个年度的底稿不能删除'),
          'warning',
          3000,
        );
        return;
      }
      const res = await paperNumber(dbname, zcbfid, item.dgnd, sjxmbh);
      if (res.success) {
        PhaseLnputDialogRef.current.show({
          args: {
            content: res.data,
            phaseName: item.text,
          },
          okCallback: async (r: boolean) => {
            if (r) {
              const res = await deletePhaseContent(dbname, zcbfid, item.dgnd, sjxmbh);
              if (res.success) {
                notify('删除成功', 'success', 3000);
                fetchData();
                props.paperPhaseTableReload(true);
              }
            }
          },
        });
      }
    } else {
      AuditPaperDeleteDialogRef.current.show({
        args: {
          title: '删除提醒',
          codes: true,
          Name: item.text,
        },
        okCallback: async () => {
          if (item.jdlx === '.') {
            notify('此数据不可删除', 'warning', 3000);
          } else {
            const res = await deletePhase(item.id, sjxmbh, dbname, username);
            if (res.success) {
              notify('删除阶段成功', 'success', 3000);
              fetchData();
              props.paperPhaseTableReload(true);
            } else {
              notify('该阶段下存在底稿，不能删除。请尝试将底稿删除再次尝试', 'warning', 3000);
            }
          }
        },
      });
    }
  };

  // 阶段右键菜单
  const menuItems = [
    {
      id: 'expand',
      icon: 'iconfont icon-zhankai',
      text: intl('phaseTree.expand', '展开所有'),
      onItemClick: () => {
        const refTree = getRefTree();
        refTree.expandAll();
      },
    },
    {
      id: 'collapse',
      icon: 'iconfont icon-shouqi',
      text: intl('phaseTree.collapse', '收起所有'),
      onItemClick: () => {
        const refTree = getRefTree();
        refTree.collapseAll();
      },
    },
    {
      id: 'new',
      icon: 'iconfont icon-xinjianjieduan',
      text: intl('phaseTree.new', '新建阶段'),
      onItemClick: (e: any) => {
        editPhase(curNodeRef.current, e.itemData.id);
      },
    },
    {
      id: 'edit',
      icon: 'iconfont icon-zhongmingming',
      text: intl('audit.paper.rename', '重命名'),
      onItemClick: (e: any) => {
        editPhase(curNodeRef.current, e.itemData.id);
      },
    },
    {
      id: 'del',
      icon: 'iconfont icon-delete',
      text: intl('audit.paper.del', '删除'),
      onItemClick: (e: any) => {
        delPhase(curNodeRef.current); // 删除
      },
    },
    {
      id: 'move',
      icon: 'iconfont icon-yidongdao',
      text: intl('audit.paper.move', '移动到'),
      onItemClick: (e: any) => {
        onMenuItemClieck({ from: 'jd', itemID: 'moveToPhase' });
      },
    },

    {
      id: 'auditPaper',
      icon: 'iconfont icon-er-digaomoban',
      text: intl('phaseTree.auditPaper', '底稿'),
      beginGroup: true,
      items: [
        {
          id: 'fromTemplte',
          text: intl('phaseTree.fromTemplte', '从底稿模板新建'),
          onItemClick: (e: { itemData: { id: any } }) => {
            onMenuItemClieck({ from: 'jd', itemID: e.itemData.id, data: curNodeRef.current });
          },
        },
        {
          id: 'fromFile',
          text: intl('phaseTree.fromFile', '从外部文件导入'),
          onItemClick: (e: { itemData: { id: any } }) => {
            onMenuItemClieck({ from: 'jd', itemID: e.itemData.id, data: curNodeRef.current });
          },
        },
        // { id: 'fromGPY', text: intl('phaseTree.fromCamera', '从高拍仪导入') },
        {
          id: 'reFromTemplte',
          text: intl('phaseTree.reFromTemplte', '从模板替换'),
          beginGroup: true,
          onItemClick: (e: { itemData: { id: any } }) => {
            onMenuItemClieck({ from: 'jd', itemID: e.itemData.id, data: curNodeRef.current });
          },
        },

        // { id: 'reFromFile', text: intl('phaseTree.reFromFile', '从外部文件替换') },
        {
          id: 'replaceFromFolder',
          text: intl('paper.replaceFromFolder', '从文件夹批量替换'),
          onItemClick: (e: { itemData: { id: any } }) => {
            onMenuItemClieck({ from: 'jd', itemID: e.itemData.id, data: curNodeRef.current });
          },
        },
      ],
    },
    {
      id: 'fromNewYear',
      icon: 'iconfont icon-xinjianniandudigao',
      text: intl('phaseTree.fromNewYear', '新建年度底稿'),
      beginGroup: true,
      onItemClick: (e: any) => {
        setShowYearlyAuditPaper(true);
        // setTimeout(() => { }, 10);
      },
    },
  ];

  // 右键菜单
  const treeViewItemContextMenu = (e: any) => {
    console.log(e.itemData, '@@@');
    treeViewRef.current?.treeRef.current.instance.selectItem(e.itemData.id);
    treeItemClick(e.itemData);
    curNodeRef.current = e.itemData;

    const lx = e.itemData.lx; // -1 回收站,0 全部,1 阶段,2 底稿
    const contextMenu: dxContextMenu | undefined = (treeViewRef.current as any)?.contextMenuRef
      ?.current?.instance;
    // contextMenu?.option('items[0].visible', canEdit); // 展开所有
    // contextMenu?.option('items[1].visible', canEdit); // 收起所有
    contextMenu?.option('items[2].visible', canEdit); // new
    contextMenu?.option('items[3].visible', canEdit); // edit
    contextMenu?.option('items[4].visible', canEdit); // del
    contextMenu?.option('items[5].visible', false); // move
    contextMenu?.option('items[6].visible', canEdit); // auditPaper
    contextMenu?.option('items[7].visible', canEdit); // new yearly auditPaper
    contextMenu?.option('items[0].disabled', !(lx > 0)); // new
    contextMenu?.option('items[1].disabled', !(lx > 0)); // new
    contextMenu?.option('items[2].disabled', !(lx > 0)); // edit
    contextMenu?.option('items[3].disabled', !(lx > 1)); // del
    contextMenu?.option('items[4].disabled', !(lx > 0)); // move
    contextMenu?.option('items[6].disabled', !(lx > 1)); // auditPaper
    contextMenu?.option('items[7].disabled', !(lx > 0)); // auditPaper

    // contextMenu?.option('items[6].disabled', !(lx > 0)); // new yearly auditPaper

    // contextMenu?.option('items[8].disabled', false);
    // contextMenu?.option('items[9].disabled', false);
  };

  const treeDragEndCallBack = useCallback(
    async (fromData: any, toData: any, action: string) => {
      // console.log('@@@', treeData, fromData, toData, action);
      if (!toData.itemData.dgnd) return;
      if (fromData.itemData.dgnd !== toData.itemData.dgnd)
        return notify('阶段禁止夸年度', 'warning', 3000);
      if (fromData.key === 'all' || fromData.key === 'recycleBin')
        return notify('该阶段不可拖', 'warning', 3000);
      const res = await PhaseMobile({
        dbName: dbname,
        fromData: fromData.itemData,
        toData: toData.itemData,
        action,
      });
      if (res.success) {
        notify('移动成功', 'success', 3000);
        fetchData(fromData.itemData.id);
      } else {
        notify('移动失败', 'error', 3000);
      }
    },
    [dbname],
  );

  const PhaseIcon = useCallback((node: any) => {
    if (node.id === 'recycleBin') {
      return (
        <div style={{ position: 'absolute', left: '0', top: '5px' }}>
          <span>
            {' '}
            <CpasIcon type={'icon-delete'} className={style.phase_Icon} />
          </span>
          {node.text}
        </div>
      );
    } else {
      return (
        <div>
          <CpasIcon type={'icon-wenjianjia'} className={style.phase_Icon} />
          {node.text}
        </div>
      );
    }
  }, []);

  const customHandleDrop = useCallback((event: any, itemData: any) => {
    event.preventDefault();

    function getFileExtension(filename: string) {
      return filename.slice(((filename.lastIndexOf('.') - 1) >>> 0) + 2);
    }
    async function sendFilesToServer(toServerFiles: any) {
      const formData = new FormData();
      toServerFiles.forEach((file: any, index: number) => {
        const { name } = file;
        const fileExtension = getFileExtension(name);
        if (modalExtensions.includes(fileExtension)) {
          formData.append(`files`, file);
        }
      });
      if (!formData.has('files')) {
        return;
      }
      try {
        const { tmpPathList, tmpPathFolder, count } = await draftManageUploadBatch(formData);
        if (tmpPathList) {
          const { dgnd, text } = itemData;
          props.fromFile_fun(dgnd, text, tmpPathList, tmpPathFolder);
        }
      } catch (e) { }
    }

    function traverseFileTree(item: any, files: any, path = '') {
      return new Promise((resolve, reject) => {
        if (item.isFile) {
          item.file((file: any) => {
            files.push(file);
            resolve(false);
          });
        } else if (item.isDirectory) {
          const dirReader = item.createReader();
          dirReader.readEntries((entries: any) => {
            const promises = [];
            for (const entry of entries) {
              promises.push(traverseFileTree(entry, files, path + item.name + '/'));
            }
            Promise.all(promises).then(resolve);
          });
        }
      });
    }

    // alert(JSON.stringify(itemData));
    const items = event.dataTransfer.items;
    // 遍历拖拽的文件
    const promises = [];
    const files: any[] = [];
    // 遍历拖拽的文件
    for (let i = 0; i < items.length; i++) {
      // 递归处理文件夹中的文件
      if (items[i].webkitGetAsEntry) {
        const entry = items[i].webkitGetAsEntry();
        promises.push(traverseFileTree(entry, files));
      }
    }
    Promise.all(promises).then(() => {
      sendFilesToServer(files);
    });
  }, []);

  return (
    <>
      {useMemo(() => {
        return (
          <div
            style={{
              display: 'flex',
              justifyContent: 'center',
              height: '100%',
            }}
          >
            <div style={{ width: '90%', height: '100%' }}>
              <SortableDevTree
                id={'shareTreeDom'}
                className="searchStyle"
                selectionMode="single"
                group={'treeGrid'}
                treeDomId={'shareTreeDom'}
                selectByClick={true}
                ref={treeViewRef}
                focusStateEnabled={true}
                gridData={treeData}
                items={treeData}
                virtualModeEnabled={true}
                treeDragEnd={treeDragEndCallBack}
                dataStructure="plain"
                displayExpr="text"
                parentIdExpr="pid"
                keyExpr="id"
                searchMode="contains"
                rootValue="all"
                searchEnabled={true}
                onItemRendered={(ItemRenderedEvent: any) => {
                  const element: any = ItemRenderedEvent.itemElement;
                  element.id = ItemRenderedEvent.itemData.ID;
                  const pid = ItemRenderedEvent.itemData.pid;
                  let lastEnterRef: any = null;
                  if (element && pid !== null && pid !== 'all') {
                    // element.removeEventListener("drop", customHandleDrop);
                    element.addEventListener('drop', (event: any) => {
                      event.preventDefault();
                      customHandleDrop(event, ItemRenderedEvent.itemData);
                      element.classList.remove('tree-item-drag-over');
                    });

                    element.addEventListener('dragover', function (event: any) {
                      event.preventDefault();
                    });

                    element.addEventListener('dragenter', function (event: any) {
                      event.preventDefault();
                      const targetEl = event.target;
                      lastEnterRef = targetEl;
                      // 可以在这里修改节点的样式以提示用户可以释放文件
                      element.classList.add('tree-item-drag-over');
                    });

                    element.addEventListener('dragleave', function (event: any) {
                      const targetEl = event.target;
                      // 在元素离开时执行的操作
                      if (lastEnterRef === targetEl) {
                        element.classList.remove('tree-item-drag-over');
                        event.stopPropagation();
                        event.preventDefault(); //事件冒泡和浏览器默认事件还是要阻止的不然不触发dropEvent事件
                      }
                    });
                  }
                  console.log(ItemRenderedEvent);
                }}
                onItemClick={(e: any) => {
                  // const refTree = getRefTree();
                  // refTree.selectItem(e.itemData.id);
                  treeItemClick(e.itemData);
                }}
                // searchEnabled={true}
                searchEditorOptions={{
                  placeholder: '',
                }}
                onItemContextMenu={treeViewItemContextMenu}
                itemRender={PhaseIcon}
                // onItemSelectionChanged={treeItemSelectionChanges}
                ContextMenu={menuItems}
              // contextMenuItemClick={contextMenuItemClick}
              />
            </div>
            <div style={Divstyle}>
              <div className="IconRefresh_Style" style={{ border: '1px solid #ddd' }}>
                <CpasIcon
                  type="icon-refresh"
                  fontSize={16}
                  onClick={() => {
                    fetchData(selNodeIDText.current);
                  }}
                />
              </div>
            </div>
          </div>
        );
      }, [treeData])}

      {useMemo(() => {
        return (
          <>
            <Popup
              width={816}
              height={590}
              onInitialized={(e: any) => {
                console.log(e, 'e-----');
              }}
              visible={showYearlyAuditPaper}
              onHiding={(e: any) => {
                setShowYearlyAuditPaper(false);
                console.log(e, '-----');
                setHidingState(true);
              }}
              title={intl('phaseTree.fromNewYear', '新建年度底稿')}
              position={{
                my: 'center',
                at: 'center',
                of: window,
              }}
              contentRender={() => {
                return (
                  <YearlyAuditPaperForm
                    fetchData={() => {
                      fetchData(selNodeIDText.current);
                    }}
                    setShowYearlyAuditPaper={setShowYearlyAuditPaper}
                    tplDialogErrorRef={tplDialogErrorRef}
                    showYearlyAuditPaper={showYearlyAuditPaper}
                    Hiding={HidingState}
                  />
                );
              }}
              resizeEnabled={true}
            />
            <AuditPaperDeleteDialog ref={AuditPaperDeleteDialogRef} />
          </>
        );
      }, [showYearlyAuditPaper, HidingState])}
      <PhaseLnputDialog ref={PhaseLnputDialogRef} />
      <DevDefaultPopup.Input ref={InputDialogRef} />
    </>
  );
});

export default PhaseTree;
